function buildJasperReportGrid() {
	
	var store = new Ext.data.JsonStore({
		totalProperty: 'reports',
	    successProperty: 'success',
	    messageProperty: 'message',  // <-- New "messageProperty" meta-data
	    idProperty: 'id',
	    root: 'data',
	
	    fields: [
	        {name: 'id', mapping: 'id', type: 'int'},
	        {name: 'report_title', mapping: 'report_title', type: 'string'},
	        {name: 'description', mapping: 'description', type: 'string'},
	        {name: 'filename', mapping: 'filename', type: 'string'},
	        {name: 'parameters', mapping: 'parameters', type: 'string'}
	    ],
	
	    // load using script tags for cross domain, if the data in on the same domain as
	    // this page, an HttpProxy would be better
	    proxy: new Ext.data.HttpProxy({
	        api: {
	    		read: BASE_URL + 'reports/getJasperReports',
	    		destroy: BASE_URL + 'reports/deleteJasperReport',
	    	},
	        method: 'POST'
	    }),
	    
	    writer: new Ext.data.JsonWriter({
		    encode: true,
		    writeAllFields: true
	    })
	});
	
	var grid = new Ext.grid.GridPanel({
		id: 'gridJasperReports',
	    width:700,
	    height:500,
	    store: store,
	    trackMouseOver:false,
	    disableSelection:true,
	    loadMask: true,
	    border: false,
	
	    columns:[
      		{header: "Id", dataIndex: 'id', sortable: true, hidden: true},
      		{header: "Id del reporte", width: 60, dataIndex: 'report_title', sortable: true},
      		{header: "Descripci&oacute;n", width: 180, dataIndex: 'description'},
      		{header: "Nombre del Archivo", dataIndex: 'filename', hidden: true},
      		{header: "Par&aacute;metros", dataIndex: 'parameters', hidden: true},
      	],
      	
      	tbar: [{
            text: 'Adicionar',
            iconCls: 'silk-report-add'
        }, '-', {
        	id: 'buttonDeleteReport',
            text: 'Eliminar',
            iconCls: 'silk-report-delete',
            disabled: true
            //handler: onDeleteJasperReport,
            //scope: store,
        }],
	
	    sm: new Ext.grid.RowSelectionModel({singleSelect: true}),
		viewConfig: {
			forceFit: true
		},
        height:210,
		split: true,
		region: 'north'
	});
	
	return grid;
}

function buildAddJasperReportForm() {
	var fp = new Ext.FormPanel({
		labelAlign: 'top',
	    fileUpload: true,
	    frame: false,
	    autoHeight: true,
	    bodyStyle: 'padding: 10px 20px 0 20px;',
	    baseCls: 'x-plain',
	    
	    defaults: {
	        allowBlank: false,
	        msgTarget: 'side',
	        anchor:'100%'
	    },
	    items: [{
	        xtype: 'textfield',
	        fieldLabel: 'Id del Reporte',
	        name: 'report_id',
	        anchor:'100%',
	        blankText: 'Este campo es requerido'
	    },{
	        xtype: 'fileuploadfield',
	        id: 'fileinput',
	        anchor:'100%',
	        emptyText: 'Selecciones un archivo Jasper Report XML (*.jrpxml)',
	        fieldLabel: 'Archivo',
	        name: 'fileupload',
	        buttonText: '',
	        buttonCfg: {
	            iconCls: 'silk-report-link'
	        },
	        blankText: 'Este campo es requerido'
	    }, {
            xtype: 'textarea',
            fieldLabel: 'Descripci&oacute;n',
            name: 'description',
            anchor:'100%',
            allowBlank: true
	    }],
	    
	});
	
	return fp;
}

function onAddJasperReport(sender) {
	var addReportForm = buildAddJasperReportForm();
	// adicionar la function validateFileExtension al objecto uploadDocumentForm para validar
	// en el cliente la extension del documento que selecciona.
	addReportForm.validateFileExtension = function() {
		var filename = this.getComponent('fileinput').getValue();
		var exp = /^.*\.(jrxml|JRXML|jrpxml|JRPXML|xml|XML)$/;
		return (exp.test(filename));
	};
	
	var w = new Ext.Window({
	    title: 'Adicionar Reporte Jasper',
	    collapsible: false,
	    maximizable: false,
	    resizable: false,
	    width: 500,
	    height: 290,
	    layout: 'fit',
	    modal: true,
	    plain: true,
	    bodyStyle: 'padding:5px;',
	    buttonAlign: 'center',
	    items: addReportForm,
	    
	    buttons: [{
	        text: 'Aceptar',
	    	handler: function() {
        		// get the form
        		var form = addReportForm.getForm();
        		if (!form.isValid()) {
        			Ext.Msg.alert('Seleccione documento', 'Por favor, selecciones un archivo Jasper Report XML v&aacute;lido');
        			return;
        		}
        		
        		// chequeameo si la extension del documento seleccionado es valido despues de dar click en aceptar
        		if (!addReportForm.validateFileExtension()) {
        			Ext.Msg.alert('Seleccione documento', 'Por favor, selecciones un archivo Jasper Report XML v&aacute;lido con extensi&oacute;n .jrxml.');
        			return;
        		}
        		
        		// si todas las validaciones se ejecutaron sin problema, nos queda por ultimo ejecutar la function submit de la forma.
                form.submit({
                    url: BASE_URL + 'reports/createJasperReportLink',
                    waitTitle: 'Por favor espere...',
                    waitMsg: 'Subiendo archivo al servidor...',
                    success: function(/*formObject*/f, /*actionObject*/a){
                        w.close();
                        var grid = sender.scope;
                        grid.store.load();
                    },
                    failure: function(/*formObject*/f, /*actionObject*/a){
                    	if (a.failureType === Ext.form.Action.CONNECT_FAILURE) {
                    		Ext.Msg.alert('Fallo', 'Server reported: '+a.response.status+' '+a.response.statusText);
                    	}
                    	if (a.failureType === Ext.form.Action.SERVER_INVALID) {
                    		Ext.MessageBox.show({
                    				title: a.result.errors.title,
                    				msg: a.result.errors.errormsg,
                    				buttons: Ext.MessageBox.OK,
                    				icon: Ext.MessageBox.ERROR,
                    	       });
                    	}
                    }
                });
            }
	    },{
	        text: 'Cancelar',
	        handler: function(){
	    		addReportForm.getForm().reset();
	            w.close();
	        }
	    }]
	});
	w.show();
}

function onDeleteJasperReport(sender) {
	var rec = this.getSelectionModel().getSelected();
    if (!rec) {
        return false;
    }
    
	Ext.Msg.show({ 
    	title: 'Eliminar reporte', 
    	buttons: Ext.MessageBox.YESNO,
    	msg: 'Desea eliminar el reporte <i>' + rec.data.report_title + '</i>?', 
    	icon: Ext.MessageBox.QUESTION,
    	
    	fn: function(btn){
				if (btn == 'yes') { 
					this.store.remove(rec);
					this.store.save();
				}
		},
		scope: this
	});
}

function showJasperReportDialog() {
	//define a template to use for the detail view
	var bookTplMarkup = [
		'Id del reporte: <a href="' + BASE_URL + 'jasper/executeReport/{filename}" target="_blank">{report_title}</a><br/>',
		'Descripci&oacute;n: {description}<br/>',
		'Archivo: {filename}<br/>',
		'Par&aacute;metros: {parameters}<br/>'
	];
	var bookTpl = new Ext.Template(bookTplMarkup);
	var grid = buildJasperReportGrid();
	// set the handle and scop to button Adicionar
	grid.getTopToolbar().items.itemAt(0).setHandler(onAddJasperReport, grid);
	// set the handle and scop to button Eliminar
	grid.getTopToolbar().items.itemAt(2).setHandler(onDeleteJasperReport, grid);
	
	var win = new Ext.Window({
	  //layout:'fit',
	  width:700,
	  height:350,
	  closeAction:'hide',
	  plain: true,
	  maximizable: true,
	  modal: true,
	  title: 'Lista de Resportes Jasper',
	  layout: 'border',
	  //frame: true,
	
	  buttons: [{
		  id: 'buttonExecuteReport',
	      text:'Executar',
	      disabled: true,
	      handler: function(btn, ev) {
			  var rec = grid.getSelectionModel().getSelected();
			  if (rec == undefined) {
				  return;
			  }
			  var url = BASE_URL + 'jasper/executeReport/' + rec.data.filename;
			  window.open(url, '_newtab');
    	  },
    	  scope: this
	  },{
	      text: 'Cerrar',
	      handler: function(){
	          win.hide();
	      }
	  }],
	  items: [
	      grid,
	      {
			id: 'detailPanel',
			region: 'center',
			minHeight: 80,
			bodyStyle: {
				background: '#ffffff',
				padding: '7px'
			},
			html: 'Por favor selecciones un reporte para ver detalles adicionales.'
		}]
	});
	
	grid.getSelectionModel().on('rowselect', function(sm, rowIdx, r) {
		var detailPanel = Ext.getCmp('detailPanel');
		bookTpl.overwrite(detailPanel.body, r.data);
		var executeButton = Ext.getCmp('buttonExecuteReport');
		executeButton.setDisabled(false);
		var deleteButton = Ext.getCmp('buttonDeleteReport');
		deleteButton.setDisabled(false);
	});
	
	// trigger the data store load
	grid.store.load();
	win.show();
}
